<?php
/** 
 * Created by RisingSun. 
 * User: MarkSpace 
 * Date: 20210822
 * Time: 11:05 
 */

define('BASE_PATH', dirname(__DIR__));

use Workerman\Protocols\Http\Response;
use Workerman\Protocols\Http\Request;


/**
 * 获取用户信息
 * @param $value
 * @return string
 */
function user($data=null){
    global $users;
    $users = $data;
    return $users;
}

/**
 * 操作日志
 * @param $value
 * @return string
 */
function logrecord($message, Array $user, String $dir='record/', String $name='') {
    $dir=config('log.path').'/'.$dir;
    if(!is_dir($dir)){mkdir($dir, 0777);}
    $name=empty($name)?date("y_m_d").".log":$name;
        $file=$dir.$name;
        // 日志内容大于1M则清空
        if(is_file($file)&&filesize($file)>20*1024*1024){
            unlink($file);
            file_put_contents($file,'');
        }
        if(is_array($user)){
            $message ='['.date('Y-m-d H:i:s',time()).'] ['.$user['id'].'-'.$user['username'].'-'.$user['realname'] .'] :'. $message;
        }
        $logcontent = $message.PHP_EOL;       
        file_put_contents($file, $logcontent, FILE_APPEND | LOCK_EX);
        unset($logcontent);
        return true;
}

/**
 * 错误日志
 * @param $value
 * @return string
 */
function errlog($message, String $name='', String $dir='err/') {
    $dir=config('log.path').'/'.$dir;
    if(!is_dir($dir)){mkdir($dir, 0777);}
    $name=empty($name)?date("y_m_d").".log":$name;
        $file=$dir.$name;
        // 日志内容大于1M则清空
        if(is_file($file)&&filesize($file)>20*1024*1024){
            unlink($file);
            file_put_contents($file,'');
        }
        $logcontent = '['.date('Y-m-d H:i:s',time()).'] :'.$message.PHP_EOL;       
        file_put_contents($file, $logcontent, FILE_APPEND | LOCK_EX);
        unset($logcontent);
        return true;
}

/**
 * 获取器: 获取随机字符
 * @param $value
 * @return false|string
 */
function getRandStr(int $length){
    //字符组合
    $str = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    $len = strlen($str)-1;
    $randstr = '';
    for ($i=0;$i<$length;$i++) {
        $num=mt_rand(0,$len);
        $randstr .= $str[$num];
    }
    return $randstr;
}

/**
 * 编号
 * @param $value
 * @return false|string
 */
function getNumID(int $length=8, String $name='count', int $type=1){
    //字符组合
    $str = date("Ymd");
    $file=config('file.basepath')."/runtime/count/".$name.".txt";
    switch (file_exists($file)) {
        case true:
            //文件存在，读文件
            $data = file_get_contents($file);
            //加一写入文件
            $data = intval($data)+1;
            file_put_contents($file,$data,LOCK_EX);
            break;
            
        default:
            //文件不存在，创建文件
            $data = 1;
            file_put_contents($file,$data,LOCK_EX);
            break;
        }
    $len = str_pad($data,$length,'0',STR_PAD_LEFT);
    $type  = str_pad($type,2,'0',STR_PAD_LEFT);
    return $str.$type.$len;
}

/**
 * 驼峰命名转下划线命名, 如 UserName => user_name
 * @param $str
 * @return string
 */
function toUnderLineName($str)
{
    $dstr = preg_replace_callback('/([A-Z]+)/', function ($matchs) {
        return '_' . strtolower($matchs[0]);
    }, $str);
    return trim(preg_replace('/_{2,}/', '_', $dstr), '_');
}

/**
 * 循环创建文件夹
 * @param $dir
 * @return bool
 */
function createFolders($dir) {
    return is_dir($dir) or (createFolders(dirname($dir)) and mkdir($dir, 0777));
}

/**
 * get请求
 * @param String $REQUEST_URI 变量
 * @param $params 值
 * @return array
 */
function get($name='*', $default = null)
{
    $url = $_SERVER['REQUEST_URI'];
    $parse = parse_url($url);
    if(isset($parse['query'])){
       parse_str($parse['query'], $params); 
    }
    switch (true) {
        case $name=='*':
            return $params;
            break;
        case isset($params[$name]):
            return $params[$name];
            break;
        default:
            return $default;
            break;
    }
}

/**
 * 读取json值
 * @param String $name 变量
 * @param $default 默认值
 * @return value
 */
function input()
{
   return file_get_contents('php://input');
}

/**
 * 读取POST值
 * @param String $name 变量
 * @param $default 默认值
 * @return value
 */
function post($name='*', $default = null)
{
    switch (true) {
        case $name=='*':
            return $_POST;
            break;
        case isset($_POST[$name]):
            return $_POST[$name];
            break;
        default:
            return $default;
            break;
    }
}

/**
* @param  $realIp
* @param true $safe_mode
* @param string $data
* @return Response
*/
function realIp($request='')
{
    switch (true) {
        case empty($request):
            $xRealIp = isset($_SERVER['HTTP_X_REAL_IP'])?$_SERVER['HTTP_X_REAL_IP']:$_SERVER['REMOTE_ADDR'];
            return $xRealIp;
            break;
        default:
            return $request->getRealIp($safe_mode=true);
            break;
    }
}

/**
* 获取设备型号
* @return Response
*/
function equipment($request='')
{
    //获取标识
    switch (true) {
        case empty($request):
            $agent = isset($_SERVER['HTTP_USER_AGENT'])?strtolower($_SERVER['HTTP_USER_AGENT']):strtolower($_SERVER['HEADER']['user-agent']);
            break;
        default:
            $agent = strtolower($request->header('user-agent'));
            break;
    }
    //获取设备型号返回类型
    switch (true) {
        case strpos($agent, 'iphone'):
            return 1;
            break;
        case strpos($agent, 'ipad'):
            return 2;
            break;
        case strpos($agent, 'android'):
            return 3;
            break;
        case strpos($agent, 'windows nt'):
            return 4;
            break;
        case strpos($agent, 'mac os'):
            return 5;
            break;
        default:
            return 6;
            break;
    }
        
}

/**
* @param  $cookie
* @param true $safe_mode
* @param string $data
* @return Response
*/
function setCert(Array $data=[])
{
    $setinfo=config('session');
    switch ($setinfo) {
        case $setinfo['usesession']==true:
            session_name($setinfo['session_name']);
            session_start();
            foreach ($data as $key => $value) {
                $_SESSION[$key]=$value;
            }
            $_SESSION['expiretime']=time() + $setinfo['expiretime'];
            break;
        case $setinfo['usecookie']==true:
            foreach ($data as $key => $value) {
                if (!setcookie($key, $value, time() + $setinfo['expiretime'], $setinfo['cookiepath'], $setinfo['domain'],$setinfo['secure'],$setinfo['http_only'])){
                    echo "set cookie failed";
                }
            }
            break;
        default:
            return false;
            break;
    } 
}

/**
* 获取起始时间戳
* @param string $type 类型 1本年 2本季度 3上月 4本月  5本周 6上周 7下周, 8获取近几天时间
* @return string
*/
function getTime(Int $type=0, Int $num=7, String $time='')
{
    switch ($type) {
        case 1://本年
            $startTime = strtotime(date("Y", time()) . "-1" . "-1");//本年开始
            $overTime = strtotime(date("Y", time()) . "-12" . "-31");//本年结束
            return ['statTime'=>$startTime,'endTime'=>$overTime];
            break;
        case 2://获取当前季度
            $season = ceil((date('m')) / 3);
            $startTime = mktime(00, 00, 00, $season * 2 + 1, 1, date('Y'));
            $overTime = mktime(23, 59, 59, $season * 3, date('t', mktime(0, 0, 0, $season * 3, 1, date("Y"))), date('Y'));
            return ['statTime'=>$startTime,'endTime'=>$overTime];
            break;
        case 3://上月
            $startTime = mktime(0,0,0,date("m")-1,1,date("Y"));
            $overTime = mktime(0,0,0,date("m"),1,date("Y"))-1;
            return ['statTime'=>$startTime,'endTime'=>$overTime];
            break;
        case 4://本月
            $startTime = mktime(0, 0, 0, date('m'), 1, date('Y'));
            $overTime = mktime(23, 59, 59, date('m'), date('t'), date('Y'));
            return ['statTime'=>$startTime,'endTime'=>$overTime];
            break;
        case 5://本周
            $startTime=mktime(0,0,0,date('m'),date('d')-date('w')+1,date('Y'));
            $overTime=mktime(23,59,59,date('m'),date('d')-date('w')+7,date('Y'));
            return ['statTime'=>$startTime,'endTime'=>$overTime];
            break;
        case 6://上周
            $startTime=mktime(0,0,0,date('m'),date('d')-date('w')+1-7,date('Y'));
            $overTime=mktime(23,59,59,date('m'),date('d')-date('w')+7-7,date('Y'));
            return ['statTime'=>$startTime,'endTime'=>$overTime];
            break;
        case 7://下周
            $startTime=mktime(0,0,0,date('m'),date('d')-date('w')+1+7,date('Y'));
            $overTime=mktime(23,59,59,date('m'),date('d')-date('w')+7+7,date('Y'));
            return ['statTime'=>$startTime,'endTime'=>$overTime];
            break;
        case 8://近多少天的数据
            $time = $time != '' ? $time : time(); 
            $date = [];
            for ($i=1; $i<=$num; $i++){
                $date[$i] = date('Y-m-d' ,strtotime( '+' . $i-$num .' days', $time));
            }
            return $date;
            break;
        default://今天
            $startTime = mktime(0,0,0,date("m"),date("d"),date("Y"));
            $overTime = mktime(0,0,0,date('m'),date('d')+1,date('Y'))-1;
            return ['statTime'=>$startTime,'endTime'=>$overTime];
            break;
    }
}

/**
 * 获取自定义的header数据
 */
function get_all_headers(){
    // 忽略获取的header数据
    $ignore = array('host','accept','content-length','content-type','cookie','connection','accept-encoding','user-agent');
    $headers = array();
    foreach($_SERVER as $key=>$value){
        if(substr($key, 0, 5)==='HTTP_'){
            $key = substr($key, 5);
            $key = str_replace('_', ' ', $key);
            $key = str_replace(' ', '-', $key);
            $key = strtolower($key);

            if(!in_array($key, $ignore)){
                $headers[$key] = $value;
            }
        }
    }
    return $headers;
}

/**
 * @fun isJson
 * @access private
 * @param  $string
 * @return mixed Returns the value provided by exec.
 */
function isJson($string) {
    json_decode($string);
    return (json_last_error() == JSON_ERROR_NONE);
}

/**
 * 错误
 * @param String $REQUEST_URI 变量
 * @param $err 值
 * @return array
 */
function err($response=''){
    $info = '<!DOCTYPE html>
            <html lang="zh-CN">
                <head>
                <meta charset="utf-8">
                <title>404 错误</title>
                <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
                <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
                <meta HTTP-EQUIV="expires" CONTENT="0">
                <style>
                    body{ font: 16px arial,\'Microsoft Yahei\',\'Hiragino Sans GB\',sans-serif; }
                    h1{ margin: 0; color:#3a87ad; font-size: 26px; }
                    .content{ width: 45%; margin: 0 auto; }
                    .content >div{ margin-top: 50px; padding: 20px; background: #d9edf7; border-radius: 12px; }
                    .content dl{ color: #2d6a88; line-height: 40px; } 
                    .content div div { padding-bottom: 20px; text-align:center; }
                </style>
                </head>
                <body>
                <div class="content">
                    <div> <h1>404 - Page Not Found 未找到</h1> </div>
                    <dl> <dt>错误说明：请求的页面不存在</dt> </dl>
                </div> 
                </body>
            </html>';
    if($response){
        return $info;
    }else{
        echo $info;
    }
}

/**
 * 基本路徑
 * @param string|false $path
 * @return string
 */
function base_path($path = ''): string
{
    return BASE_PATH . ($path ? (DIRECTORY_SEPARATOR . ltrim($path, DIRECTORY_SEPARATOR)) : $path);
}

/**
 * Json response
 * @param $data
 * @param int $options
 * @return Response
 */
function json($data, int $options = JSON_UNESCAPED_UNICODE): Response
{
    return new Response(200, ['Content-Type' => 'application/json','Server'=>config('server.name')], json_encode($data, $options));
}

/**
 * Xml response
 * @param $xml
 * @return Response
 */
function xml($xml): Response
{
    if ($xml instanceof SimpleXMLElement) {
        $xml = $xml->asXML();
    }
    return new Response(200, ['Content-Type' => 'text/xml','Server'=>config('server.name')], $xml);
}

/**
 * Jsonp response
 * @param $data
 * @param string $callbackName
 * @return Response
 */
function jsonp($data, string $callbackName = 'callback'): Response
{
    if (!is_scalar($data) && null !== $data) {
        $data = json_encode($data);
    }
    return new Response(200, ['Content-Type' => 'application/object','Server'=>config('server.name')], "$callbackName($data)");
}

/**
 * Redirect response
 * @param string $location
 * @param int $status
 * @param array $headers
 * @return Response
 */
function redirect(string $location, int $status = 302, array $headers = []): Response
{
    $response = new Response($status, ['Location' => $location]);
    if (!empty($headers)) {
        $response->withHeaders($headers);
    }
    return $response;
}

/**
 * Get config
 * @param string|null $key
 * @param $default
 * @return array|mixed|null
 */
function config(string $key = null, $default = '/config')
{
    return Mscore\Core\Config::get($key, $default);
}

/**
 * Copy dir
 * @param string $source
 * @param string $dest
 * @param bool $overwrite
 * @return void
 */
function copy_dir(string $source, string $dest, bool $overwrite = false)
{
    if (is_dir($source)) {
        if (!is_dir($dest)) {
            mkdir($dest);
        }
        $files = scandir($source);
        foreach ($files as $file) {
            if ($file !== "." && $file !== "..") {
                copy_dir("$source/$file", "$dest/$file", $overwrite);
            }
        }
    } else if (file_exists($source) && ($overwrite || !file_exists($dest))) {
        copy($source, $dest);
    }
}

/**
 * Remove dir
 * @param string $dir
 * @return bool
 */
function remove_dir(string $dir, bool $deldir=true): bool
{
    if(!is_dir($dir)){ return true; }
    if ((is_link($dir) || is_file($dir))&&$deldir==true) {
        return unlink($dir);
    }
    $files = array_diff(scandir($dir), array('.', '..'));
    foreach ($files as $file) {
        (is_dir("$dir/$file") && !is_link($dir)) ? remove_dir("$dir/$file") : unlink("$dir/$file");
    }
    if($deldir==true){ return rmdir($dir); }
    return true;
}

/**
 * Is phar
 * @return bool
 */
function is_phar(): bool
{
    return class_exists(Phar::class, false) && Phar::running();
}

/**
 * Get cpu count
 * @return int
 */
function cpu_count(): int
{
    // Windows does not support the number of processes setting.
    if (DIRECTORY_SEPARATOR === '\\') {
        return 1;
    }
    $count = 4;
    if (is_callable('shell_exec')) {
        if (strtolower(PHP_OS) === 'darwin') {
            $count = (int)shell_exec('sysctl -n machdep.cpu.core_count');
        } else {
            $count = (int)shell_exec('nproc');
        }
    }
    return $count > 0 ? $count : 4;
}

/**
 * probability 概率计算
 * @return int
 */
function probability($probability) {
    // 假设输入的概率是一个0到1之间的数
    // 如果输入的概率不在这个范围内，则返回false
    if ($probability <= 0 || $probability > 1) {
        return false;
    }
    // 生成一个0到1之间的随机数
    $random = mt_rand() / mt_getrandmax();
    // 比较随机数与输入的概率
    return $random < $probability;
}
/**
 * matchIpSegment 匹配Ip
 * @return boolean
 */
function matchip($ip, $ipSegment) {
    // 将IP段分割成网络地址和子网掩码
    list($network, $mask) = explode('/', $ipSegment);
    
    // 将子网掩码转换为255.255.255.255中的值
    $mask = str_repeat('255.', $mask) . '0.0.0';
    $pattern = str_replace('255', '\d+', $mask); // 创建正则表达式
    
    // 创建完整的正则表达式
    $regex = '/^' . str_replace('.', '\\.', $network) . '$/';
    $regex .= '(?i)' . str_replace('255', '(?:\d{1,3})', $pattern); // 不区分大小写匹配
    
    // 使用正则表达式进行匹配
    return preg_match($regex, $ip);
}